<?php
/**
 * Created by PhpStorm.
 * Author: 芸签cms www.yunqiancms.com
 * User: sun
 * Date: 2022/6/23
 * Time: 4:21 PM
 */

namespace app\common\helpers;

use app\common\exceptions\BizException;

class HttpHelper
{
    public static $connectTimeout = 30;//30 second
    public static $readTimeout = 80;//80 second

    public static function doPost($url,$data,$header=null){
        return self::curl($url,'POST',$data,$header);
    }
    public static function doPut($url,$data,$header=null){
        //\Log::debug('doPut url', $url);

        return self::curl($url,'PUT',$data,$header);
    }
    public static function doGet($url,$data,$header){
        if(count($data)>0){
            $url = $url.'?'.http_build_query($data);
        }
        return self::curl($url,'GET',$data,$header);
    }
    public static function doDelete($url,$data,$header){
        return self::curl($url,'DELETE',$data,$header);
    }

    public static function curl($url, $httpMethod = "GET", $postFields = null,$headers = array())
    {
        if(empty($headers)){
            $headers = ["Content-Type:application/json;charset=UTF-8"];
        }
        $headers[] = 'Expect:';

        $ch = curl_init();
        curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $httpMethod);
        /*if(ENABLE_HTTP_PROXY) {
            curl_setopt($ch, CURLOPT_PROXYAUTH, CURLAUTH_BASIC);
            curl_setopt($ch, CURLOPT_PROXY, HTTP_PROXY_IP);
            curl_setopt($ch, CURLOPT_PROXYPORT, HTTP_PROXY_PORT);
            curl_setopt($ch, CURLOPT_PROXYTYPE, CURLPROXY_HTTP);
        }*/
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_FAILONERROR, false);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

//        curl_setopt($ch, CURLOPT_POSTFIELDS, is_array($postFields) ? self::getPostHttpBody($postFields) : $postFields);

        $postData = is_array($postFields) ? json_encode($postFields, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE) : $postFields;
        curl_setopt($ch, CURLOPT_POSTFIELDS,$postData );

        if (self::$readTimeout) {
            curl_setopt($ch, CURLOPT_TIMEOUT, self::$readTimeout);
        }

        if (self::$connectTimeout) {
            curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, self::$connectTimeout);
        }

        if(strlen($url) > 5 && strtolower(substr($url,0,5)) == "https" ) {
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
            curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        }

        if (is_array($headers) && 0 < count($headers))
        {
            curl_setopt($ch,CURLOPT_HTTPHEADER,$headers);
        }

        $curlRes = curl_exec($ch);
        //\Log::debug('$curlRes', $curlRes);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);
        \Log::debug('httphelper:url:', $url);
        \Log::debug('httphelper:curlRes:', $httpCode.'||'.$curlRes);
        \Log::debug('httphelper:postData:', $postData);
        if($httpCode != 200){
            \Log::debug('httphelper:url:', $url);
            \Log::debug('httphelper:curlRes:', $httpCode.'||'.$curlRes);
            \Log::debug('httphelper:postData:', $postData);
            throw new BizException('请求失败');
        }

        return $curlRes;
    }
    static function postFile($url, array $keysArr = array())
    {

        // invalid characters for "name" and "filename"
        static $disallow = array("\0", "\"", "\r", "\n");

        $body = array();
        // build normal parameters
        foreach ($keysArr as $k => $v) {
            //var_dump($keysArr);
            if ($k == 'file') {
                $data = self::getFileStream($v->name);
                if(is_array($data)){
                    return $data;
                }
                $srcPath = self::encodePath($v->name);
                $file = '@'.$srcPath;

                $body[] = implode("\r\n", array(
                    "Content-Disposition: form-data; name=\"file\"; filename=\"{$file}\"",
                    "Content-Type: application/octet-stream",
                    "",
                    $data,
                ));
            }

            $k = str_replace($disallow, "_", $k);
            $body[] = implode("\r\n", array(
                "Content-Disposition: form-data; name=\"{$k}\"",
                "",
                filter_var($v),
            ));
        }

        // generate safe boundary
        do {
            $boundary = "---------------------" . md5(mt_rand() . microtime());
        } while (preg_grep("/{$boundary}/", $body));

        // add boundary for each parameters
        array_walk($body, function (&$part) use ($boundary) {
            $part = "--{$boundary}\r\n{$part}";
        });

        // add final boundary
        $body[] = "--{$boundary}--";
        $body[] = "";

//        echo $url;exit;
        $res = self::doPost(
            $url,
            implode("\r\n", $body),
            $header = array(
                "Content-Type: multipart/form-data; boundary={$boundary}",
            )
        );

        return $res;
    }

    static function getFileStream($filePath){
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, $filePath);
        curl_setopt($curl, CURLOPT_REFERER, '');
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($curl, CURLOPT_HEADER, true); // 输出HTTP头 true
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);//SSL证书认证
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
        curl_setopt($curl, CURLOPT_TIMEOUT, 30);

        $result = curl_exec($curl);
        $httpCode = curl_getinfo($curl,CURLINFO_HTTP_CODE);

        if($httpCode != 200){
            if(isset($httpCodeMap[$httpCode])){
                return array('errCode'=>$httpCode,'msg'=>getCurlErrMap($httpCode));
            }
            $info['errCode'] = $httpCode;
            return $info;
        }

        return $result;
    }

    /**
     * 检查是否是中文编码
     * @param $str
     * @return int
     */
    public static function chkChinese($str)
    {
        return preg_match('/[\x80-\xff]./', $str);
    }

    /**
     * 检测是否windows系统，因为windows系统默认编码为GBK
     * @return bool
     */
    public static function isWin()
    {
        return strtoupper(substr(PHP_OS, 0, 3)) == "WIN";
    }

    /**
     * 主要是由于windows系统编码是gbk，遇到中文时候，如果不进行转换处理会出现找不到文件的问题
     * @param $file_path
     * @return string
     */
    public static function encodePath($file_path)
    {
        if (self::chkChinese($file_path) && self::isWin()) {
            $file_path = iconv('utf-8', 'gbk', $file_path);
        }

        return $file_path;
    }

    static function getPostHttpBody($postFildes){
        $content = "";
        foreach ($postFildes as $apiParamKey => $apiParamValue)
        {
            if(is_string($apiParamValue)){
                $content .= "$apiParamKey=" . urlencode($apiParamValue) . "&";
            }
        }

        return substr($content, 0, -1);
    }
    static function getHttpHearders($headers)
    {
        $httpHeader = array();
        foreach ($headers as $key => $value)
        {
            array_push($httpHeader, $key.":".$value);
        }

        return $httpHeader;
    }

    static function writeLog($text) {
        if(is_array($text) || is_object($text)){
            $text = json_encode($text);
        }

        file_put_contents ( "log/log.txt", date ( "Y-m-d H:i:s" ) . "  " . $text . "\r\n", FILE_APPEND );
    }
    static function sendPdfPUT($uploadUrls, $header, $fileContent){

        $status = '';
        $curl_handle = curl_init();
        curl_setopt($curl_handle, CURLOPT_URL, $uploadUrls);
        curl_setopt($curl_handle, CURLOPT_FILETIME, true);
        curl_setopt($curl_handle, CURLOPT_FRESH_CONNECT, false);
        curl_setopt($curl_handle, CURLOPT_HEADER, true); // 输出HTTP头 true
        curl_setopt($curl_handle, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($curl_handle, CURLOPT_TIMEOUT, 5184000);
        curl_setopt($curl_handle, CURLOPT_CONNECTTIMEOUT, 120);
        curl_setopt($curl_handle, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($curl_handle, CURLOPT_SSL_VERIFYHOST, false);

        curl_setopt($curl_handle, CURLOPT_HTTPHEADER, $header);
        curl_setopt($curl_handle, CURLOPT_CUSTOMREQUEST, 'PUT');

        curl_setopt($curl_handle, CURLOPT_POSTFIELDS, $fileContent);
        $result = curl_exec($curl_handle);
        $status = curl_getinfo($curl_handle, CURLINFO_HTTP_CODE);

        if ($result === false) {
            $status = curl_errno($curl_handle);
            $result = 'put file to oss - curl error :' . curl_error($curl_handle);
        }
        curl_close($curl_handle);
//    $this->debug($url, $fileContent, $header, $result);
        return $status;
    }
    static function getRealFileIgnore($filePath)
    {
        if (class_exists('\CURLFile')) {
            return new \CURLFile($filePath);

        } else {
            return '@' . $filePath;
        }
    }


    // 判断是网络路径还是文件路径
    static function isUrl($url){
        $parse = parse_url($url);
        $scheme = $parse['scheme'];
        $scheme = strtolower($scheme);
        if("http" == $scheme){
            return true;
        }

        if("https" == $scheme){
            return true;
        }
        return false;
    }
}